from django.shortcuts import render,HttpResponse
import json
from web.forms.file import FolderModelForm,FileModelForm
from django.http import JsonResponse
from django.forms import model_to_dict
from django.urls import reverse
from utils.tencent.cos import delete_file,delete_file_list,credential
from django.views.decorators.csrf import csrf_exempt
from web import models
# http://127.0.0.1:8000/manage/10/file

# http://127.0.0.1:8000/manage/10/file/?folder=9
def file(request,project_id):
    """ 文件列表 添加文件夹 """
    parent_object = None
    folder_id = request.GET.get('folder', "")
    if folder_id.isdecimal():  # isdecimal() 是否十进制的数
        parent_object = models.FileRepository.objects.filter(id=int(folder_id), file_type=2,
                                                             project=request.tracer.project).first()
    # 查看页面
    if request.method == "GET":
        # 导航条
        breadcrumb_list = []
        parent = parent_object
        while parent:
            # breadcrumb_list.insert(0,{'id':parent.id,'name':parent.name}) 相当于下面的代码
            breadcrumb_list.insert(0, model_to_dict(parent,['id','name']))
            parent = parent.parent

        # 当前目录下所有的文件  文件夹获取到即可
        queryset = models.FileRepository.objects.filter(project=request.tracer.project)
        if parent_object:
            # 进入某目录
            file_object_list = queryset.filter(parent=parent_object).order_by('-file_type')
        else:
            # 根目录
            file_object_list = queryset.filter(parent__isnull=True).order_by('-file_type')
        form = FolderModelForm(request,parent_object)
        context = {'form':form,
                   'file_object_list':file_object_list,
                   'breadcrumb_list': breadcrumb_list,
                   'folder_object': parent_object,
                   }
        return render(request,'file.html',context)
    # 添加文件夹 文件夹的修改
    fid = request.POST.get('fid',"")
    edit_object = None
    if fid.isdecimal():
        # 修改
        edit_object = models.FileRepository.objects.filter(id=int(fid), file_type=2,
                                             project=request.tracer.project).first()
    if edit_object:
        form = FolderModelForm(request, parent_object, data=request.POST,instance=edit_object)
    else:
        form = FolderModelForm(request, parent_object, data=request.POST)

    if form.is_valid():
        form.instance.project = request.tracer.project
        form.instance.file_type = 2
        form.instance.update_user = request.tracer.user
        form.instance.parent =  parent_object
        form.save()
        return JsonResponse({'status': True})
    return JsonResponse({'status':False,'error':form.errors})

# http://127.0.0.1:8000/manage/10/file/delete?fid=9
def file_delete(request,project_id):
    """ 删除文件 """
    fid = request.GET.get('fid')
    # 删除数据库中的文件  和 文件夹（级联删除）
    delete_object = models.FileRepository.objects.filter(id=fid,project=request.tracer.project).first()
    if delete_object.file_type == 1:

        # 字节  删除文件，将容量还给当前项目的已使用空间
        request.tracer.project.use_space -= delete_object.file_size
        request.tracer.project.save()
        # 去 cos中删除文件
        delete_file(request.tracer.project.bucket,request.tracer.project.region,delete_object.key)
        # 在数据库中删除当前文件
        delete_object.delete()
        return JsonResponse({'status': True})

    # 删除文件夹（找到文件夹下的所有的文件-》数据库文件删除。cos文件删除，项目已使用空间容量还回去）
    # 找他下面的  文件 和文件夹
    # models.FileRepository.objects.filter(parent=delete_object) 文件删除 ；文件夹继续向里查

    total_size = 0
    folder_list = [delete_object,]
    key_list = []
    for folder in folder_list:
        child_list = models.FileRepository.objects.filter(project=request.tracer.project,parent=folder).order_by('-file_type')
        for child in child_list:
            if child.file_type == 2:
                folder_list.append(child)
            else:
                # 文件大小汇总
                total_size += child.file_size
                # 删除这个文件
                # delete_file(request.tracer.project.bucket, request.tracer.project.region, child.key)  太慢一个一个删除
                key_list.append({"Key": child.key})

    # cos 批量删除文件
    if key_list:
        delete_file_list(request.tracer.project.bucket,request.tracer.project.region,key_list)
    # 还会容量
    if total_size:
        request.tracer.project.use_space -= total_size
        request.tracer.project.save()
    delete_object.delete()
    return JsonResponse({'status': True})
@csrf_exempt
def cos_credential(request,project_id):
    """ 获取cos上传临时凭证 """
    # 做容量限制；单文件  总容量
    per_file_limit = request.tracer.price_policy.per_file_size * 1024 * 1024
    total_file_limit = request.tracer.price_policy.project_space * 1024 * 1024 * 1024
    total_size = 0
    file_list = json.loads(request.body.decode('utf-8'))
    for item in file_list:
        # 文件的字节大小 item['size'] = B
        # 单文件的限制大小 M
        # 超出限制
        if item['size'] > per_file_limit:
            msg = "单文件超出限制(最大{}M,文件:{},请升级套餐".format(request.tracer.price_policy.per_file_size,item['name'])
            return JsonResponse({'status':False,'error':msg})
        total_size += item['size']

    # 总容量进行限制
    # request.tracer.price_policy.project_space  # 项目的允许的空间
    # request.tracer.project.use_space    # 项目的已使用的空间
    if request.tracer.project.use_space + total_size > total_file_limit:

        return JsonResponse({'status': False, 'error': '容量超过限制，请升级套餐'})
    data_dict = credential(request.tracer.project.bucket,request.tracer.project.region)
    return JsonResponse({'status':True,'data':data_dict})
@csrf_exempt
def file_post(request,project_id):
    """ 已上传成功的文件写入到数据 """
    # 根据key再去cos获取文件ETAG和对比
    # request.POST.get('name')
    # request.POST.get('size')

    form = FileModelForm(request,data=request.POST)

    if form.is_valid():
        # 校验通过 写入数据库
        # 通过ModelForm。save存储到数据库中的数据返回的instance对象，无法通过get_xx_display获取choice的中文
        # form.instance.file_type = 1
        # form.update_user = request.tracer.user
        # instance = form.save()   # 添加成功之后，获取到的新添加的那个对象（instance.id,instance.name,instance.file_type
        print(form, 22)
        data_dict = form.cleaned_data

        data_dict.pop('etag')
        data_dict.update({'project':request.tracer.project,'file_type': 1, 'update_user':request.tracer.user})
        instance = models.FileRepository.objects.create(**data_dict)
        # 项目的以已使用空间，更新
        request.tracer.project.use_space += data_dict['file_size']
        request.tracer.project.save()
        res = {
            'id': instance.id,
            'name':instance.name,
            'file_size': instance.file_size,
            'username':instance.update_user.username,
            'datetime': instance.update_datetime.strftime("%Y年%m月%d日 %H:%M"),
            'download_url':reverse('file_download',kwargs={"project_id":project_id,'file_id':instance.id})
            # 'file_type': instance.get_file_type_display()
        }
        return JsonResponse({'status':True,'data':res})
    return JsonResponse({'status':False,'data':'文件错误'})

def file_download(request,project_id,file_id):
    """ 下载文件 """
    # 文件内容 去cos获取文件内容
    # with open('xxx.png',mode="rb") as f
    #     data = f.read()
    # 响应头
    import requests
    file_object = models.FileRepository.objects.filter(id=file_id,project_id=project_id).first()
    res = requests.get(file_object.file_path)
    # 文件分块处理（适用于大文件)
    data = res.iter_content()
    # 设置content_type=application/octet-stream 用于提示下载框
    response = HttpResponse(data,content_type="application/octet_stream")
    from django.utils.encoding import escape_uri_path
    # 设置响应头:中文文件转义
    response['Content-Disposition'] = "attachment; filename={}".format(escape_uri_path(file_object.name))
    return response
